package util

import (
	"database/sql"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
	"math"
	"nspel/entity"
	"regexp"
	"strconv"
	"strings"
	"time"
)

func validateExcelColumn(array *[][]string, beginRow int64, column *[]string) (errMsg []ImportErrorMsg, columnMap map[string]int) {
	if len(*array) <= 1 {
		errMsg = append(errMsg, ImportErrorMsg{At: "-", Reason: "空表格"})
		return
	}
	columnMap = make(map[string]int)
	for i := 0; i < len((*array)[beginRow]); i++ {
		columnMap[(*array)[beginRow][i]] = i
	}
	for i := 0; i < len(*column); i++ {
		if _, o := columnMap[(*column)[i]]; !o {
			errMsg = append(errMsg, ImportErrorMsg{At: "-", Reason: "字段" + (*column)[i] + "不存在"})
		}
	}
	return
}

func validateCountry(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string) (countryId int64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, nil
	} else {
		country := new(entity.Country)
		err = country.SelectAllByName((*array)[row][column])
		return country.Id, err
	}
}

func validateProvince(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string) (provinceId int64, countryId int64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, 0, nil
	} else {
		province := new(entity.Province)
		err := province.SelectAllByName((*array)[row][column])
		if err == orm.ErrNoRows {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]不存在"})
			err = nil
		}
		return province.Id, province.CountryId, err
	}
}

func validateProvinceWithCountry(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, countryId int64, countryName string, columnName string, countryColumnName string) (provinceId int64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, nil
	} else {
		province := new(entity.Province)
		err := province.SelectAllByName((*array)[row][column])
		if err == orm.ErrNoRows {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]不存在"})
			err = nil
		} else if countryId != 0 {
			if province.CountryId != countryId {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: countryColumnName + "[" + countryName + "]不存在" + columnName + "[" + (*array)[row][column] + "]"})
			}
		}
		return province.Id, err
	}
}

func validateCityWithProvince(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, provinceId int64, provinceName string, columnName string, provinceColumnName string) (cityId int64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, nil
	} else {
		city := new(entity.City)
		cities, err := city.SelectAllByName((*array)[row][column])
		if err == nil && len(*cities) == 0 {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]不存在"})
		} else if provinceId != 0 {
			err = city.SelectAllByProvinceIdName(provinceId, (*array)[row][column])
			if err == orm.ErrNoRows {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: provinceColumnName + "[" + provinceName + "]不存在" + columnName + "[" + (*array)[row][column] + "]"})
				err = nil
			}
		}
		return city.Id, err
	}
}

func validateAreaIsNew(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, cityId int64, columnName string) (areaId int64, userId sql.NullInt64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, sql.NullInt64{Int64: 0, Valid: false}, nil
	} else {
		area := new(entity.Area)
		if cityId != 0 {
			err = area.SelectAllByCityIdName(cityId, (*array)[row][column])
			if err == orm.ErrNoRows {
				err = nil
			}
		}
		return area.Id, area.UserId, err
	}
}

func validateAreaWithCity(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, cityId int64, cityName string, columnName string, cityColumnName string) (areaId int64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, nil
	} else {
		area := new(entity.Area)
		areas, err := area.SelectAllByName((*array)[row][column])
		if err == nil && len(*areas) == 0 {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]不存在"})
		} else if cityId != 0 {
			err = area.SelectAllByCityIdName(cityId, (*array)[row][column])
			if err == orm.ErrNoRows {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: cityColumnName + "[" + cityName + "]不存在" + columnName + "[" + (*array)[row][column] + "]"})
				err = nil
			}
		}
		return area.Id, err
	}
}

func validateSchoolCode(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string) (schoolId int64, countryId int64, provinceId int64, cityId int64, areaId int64, experimentAreaId int64, schoolType byte, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, 0, 0, 0, 0, 0, 0, nil
	} else {
		school := new(entity.School)
		err = school.SelectAllBySchoolCode((*array)[row][column])
		if err == orm.ErrNoRows {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "不存在"})
			err = nil
		}
		return school.Id, school.CountryId, school.ProvinceId, school.CityId, school.AreaId, school.ExperimentAreaId, school.SchoolType, err
	}
}

func validateSchoolIsNew(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string) (schoolId int64, userId sql.NullInt64, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, sql.NullInt64{Int64: 0, Valid: false}, nil
	} else {
		school := new(entity.School)
		err = school.SelectAllBySchoolCode((*array)[row][column])
		if err == orm.ErrNoRows {
			err = nil
		}
		return school.Id, school.UserId, err
	}
}

func validateString(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) string {
	valid := validation.Validation{}
	valid.MaxSize((*array)[row][column], maxLength, "")
	if valid.HasErrors() {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "长度大于" + strconv.Itoa(maxLength)})
	} else {
		valid.MinSize((*array)[row][column], minLength, "")
		if valid.HasErrors() {
			if len((*array)[row][column]) == 0 {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
			} else {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "长度小于" + strconv.Itoa(minLength)})
			}
		}
	}
	return (*array)[row][column]
}

func validateIdentityId(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) (nullStr sql.NullString) {
	(*array)[row][column] = strings.Replace((*array)[row][column], "\t", "", -1)
	return validateNullString(array, row, column, errMsg, minLength, maxLength, columnName)
}

func validateStudentNumber(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) (str string) {
	(*array)[row][column] = strings.Replace((*array)[row][column], "\t", "", -1)
	return validateString(array, row, column, errMsg, minLength, maxLength, columnName)
}

func validateNullString(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) (nullStr sql.NullString) {
	nullStr.String = validateString(array, row, column, errMsg, minLength, maxLength, columnName)
	if len(nullStr.String) != 0 {
		nullStr.Valid = true
	}
	return
}

func validatePhone(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) string {
	valid := validation.Validation{}
	valid.MinSize((*array)[row][column], minLength, "")
	if valid.HasErrors() {
		if len((*array)[row][column]) == 0 {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		} else {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "长度小于" + strconv.Itoa(minLength)})
		}
	} else if len((*array)[row][column]) > 0 {
		valid.MaxSize((*array)[row][column], maxLength, "")
		if valid.HasErrors() {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "长度大于" + strconv.Itoa(maxLength)})
		} else {
			valid.Phone((*array)[row][column], "")
			if valid.HasErrors() {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			}
		}
	}
	return (*array)[row][column]
}

func validateNullPhone(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) (nullStr sql.NullString) {
	nullStr.String = validatePhone(array, row, column, errMsg, minLength, maxLength, columnName)
	if len(nullStr.String) != 0 {
		nullStr.Valid = true
	}
	return
}

func validateAreaUser(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, authority byte, columnName string, areaId int64, phoneMap *map[interface{}]int) error {
	if len((*array)[row][column]) == 0 {
		return nil
	}
	if sameRow, ok := (*phoneMap)[(*array)[row][column]]; ok {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "与第" + strconv.Itoa(sameRow) + "行联系电话重复"})
		return nil
	} else {
		(*phoneMap)[(*array)[row][column]] = row + 1
	}
	manager := new(entity.Manager)
	err := manager.SelectAllByUserName((*array)[row][column])
	if err != nil {
		if err == orm.ErrNoRows {
			return nil
		} else {
			return err
		}
	}
	if manager.Authority != authority || areaId == 0 {
		if manager.Authority == entity.ManagerAuthority.Administrator {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是超级管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.Province {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是省管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.City {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是市管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.Area {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是区管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.School {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是校管理员账号"})
		}
	} else {
		area := new(entity.Area)
		err = area.SelectAllByUserId(manager.Id)
		if err != nil {
			return err
		} else {
			if area.Id != areaId {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "与其他区账号重复"})
			}
		}
	}
	return nil
}

func validateSchoolUser(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, authority byte, columnName string, shcoolId int64, phoneMap *map[interface{}]int) error {
	if len((*array)[row][column]) == 0 {
		return nil
	}
	if sameRow, ok := (*phoneMap)[(*array)[row][column]]; ok {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "与第" + strconv.Itoa(sameRow) + "行联系电话重复"})
		return nil
	} else {
		(*phoneMap)[(*array)[row][column]] = row + 1
	}
	manager := new(entity.Manager)
	err := manager.SelectAllByUserName((*array)[row][column])
	if err != nil {
		if err == orm.ErrNoRows {
			return nil
		} else {
			return err
		}
	}
	if manager.Authority != authority || shcoolId == 0 {
		if manager.Authority == entity.ManagerAuthority.Administrator {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是超级管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.Province {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是省管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.City {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是市管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.Area {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是区管理员账号"})
		} else if manager.Authority == entity.ManagerAuthority.School {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "已经是校管理员账号"})
		}
	} else {
		school := new(entity.School)
		err = school.SelectAllByUserId(manager.Id)
		if err != nil {
			return err
		} else {
			if school.Id != shcoolId {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]" + "与其他校账号重复"})
			}
		}
	}
	return nil
}

func validateEmail(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) string {
	valid := validation.Validation{}
	valid.MinSize((*array)[row][column], minLength, "")
	if valid.HasErrors() {
		if len((*array)[row][column]) == 0 {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		} else {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "长度小于" + strconv.Itoa(minLength)})
		}
	} else if len((*array)[row][column]) > 0 {
		valid.MaxSize((*array)[row][column], maxLength, "")
		if valid.HasErrors() {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "长度大于" + strconv.Itoa(maxLength)})
		} else {
			valid.Email((*array)[row][column], "")
			if valid.HasErrors() {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			}
		}
	}
	return (*array)[row][column]
}

func validateNullEmail(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minLength int, maxLength int, columnName string) (nullStr sql.NullString) {
	nullStr.String = validateEmail(array, row, column, errMsg, minLength, maxLength, columnName)
	if len(nullStr.String) != 0 {
		nullStr.Valid = true
	}
	return
}

func validateInt(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minInt int64, maxInt int64, isRequire bool, defaultValue int64, columnName string) int64 {
	if len((*array)[row][column]) == 0 {
		if isRequire {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		}
		return defaultValue
	} else {
		value, err := strconv.ParseInt((*array)[row][column], 10, 64)
		if err != nil {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
		} else {
			if value > maxInt {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]大于" + strconv.FormatInt(maxInt, 10)})
			} else if value < minInt {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]小于" + strconv.FormatInt(minInt, 10)})
			}
		}
		return value
	}
}

func validateNullInt(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minInt int64, maxInt int64, isRequire bool, defaultValue int64, columnName string) (nullInt64 sql.NullInt64) {
	nullInt64.Int64 = int64(validateInt(array, row, column, errMsg, minInt, maxInt, isRequire, defaultValue, columnName))
	if len((*array)[row][column]) != 0 {
		nullInt64.Valid = true
	}
	return
}

func validateFloat64(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minFloat64 float64, maxFloat64 float64, isRequire bool, defaultValue float64, columnName string) float64 {
	if len((*array)[row][column]) == 0 {
		if isRequire {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		}
		return defaultValue
	} else {
		value, err := strconv.ParseFloat((*array)[row][column], 64)
		if err != nil {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
		} else {
			if value > maxFloat64 {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]大于" + strconv.FormatFloat(maxFloat64, 'f', 2, 64)})
			} else if value < minFloat64 {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]小于" + strconv.FormatFloat(minFloat64, 'f', 2, 32)})
			}
		}
		return value
	}
}

func validateNullFloat64(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minFloat64 float64, maxFloat64 float64, isRequire bool, defaultValue float64, columnName string) (nullFloat64 sql.NullFloat64) {
	nullFloat64.Float64 = validateFloat64(array, row, column, errMsg, minFloat64, maxFloat64, isRequire, defaultValue, columnName)
	if len((*array)[row][column]) != 0 {
		nullFloat64.Valid = true
	}
	return
}
func validateMinuteSecond(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minSecond float64, maxSecond float64, isRequire bool, defaultValue float64, columnName string) float64 {
	if len((*array)[row][column]) == 0 {
		if isRequire {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		}
		return defaultValue
	} else {
		if ok, _ := regexp.MatchString(`^\d+′\d{2}$`, (*array)[row][column]); ok {
			times := strings.Split((*array)[row][column], "′")
			minute, _ := strconv.Atoi(times[0])
			second, _ := strconv.Atoi(times[1])
			if second >= 60 {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			} else {
				return float64(minute*60 + second)
			}
		} else if ok, _ := regexp.MatchString(`\d+'\d{2}`, (*array)[row][column]); ok {
			times := strings.Split((*array)[row][column], "'")
			minute, _ := strconv.Atoi(times[0])
			second, _ := strconv.Atoi(times[1])
			if second >= 60 {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			} else {
				return float64(minute*60 + second)
			}
		} else {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
		}
		return defaultValue
	}
}

func validateNullMinuteSecond(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minSecond float64, maxSecond float64, isRequire bool, defaultValue float64, columnName string) (nullFloat64 sql.NullFloat64) {
	nullFloat64.Float64 = validateMinuteSecond(array, row, column, errMsg, minSecond, maxSecond, isRequire, defaultValue, columnName)
	if len((*array)[row][column]) != 0 {
		nullFloat64.Valid = true
	}
	return
}

func validateEnum(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, isRequire bool, defaultValue interface{}, enumMap map[string]interface{}, columnName string) interface{} {
	if len((*array)[row][column]) == 0 {
		if isRequire {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		}
		return defaultValue
	} else {
		value, ok := enumMap[(*array)[row][column]]
		if !ok {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			return defaultValue
		}
		return value
	}
}

func validateDate(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, minYear int, maxYear int, isRequire bool, columnName string) time.Time {
	if len((*array)[row][column]) == 0 {
		if isRequire {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		}
		return *new(time.Time)
	} else {
		var date time.Time
		if ok, _ := regexp.MatchString(`^\d{5}$`, (*array)[row][column]); ok {
			baseTime, _ := time.Parse("2006-01-02", "1899-12-30")
			days, _ := strconv.Atoi((*array)[row][column])
			duration, _ := time.ParseDuration(strconv.Itoa(days*24) + "h")
			date = baseTime.Add(duration).Local()
		} else if ok, _ := regexp.MatchString(`^\d{2}-\d{2}-\d{2}$`, (*array)[row][column]); ok {
			parsedDate, err := time.Parse("2006-01-02", "20"+(*array)[row][column][6:]+"-"+(*array)[row][column][0:5])
			if err != nil {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			}
			date = parsedDate.Local()
		} else if ok, _ := regexp.MatchString(`^\d{4}-\d{2}-\d{2}$`, (*array)[row][column]); ok {
			parsedDate, err := time.Parse("2006-01-02", (*array)[row][column])
			if err != nil {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			}
			date = parsedDate.Local()
		} else if ok, _ := regexp.MatchString(`^\d{4}/\d{2}/\d{2}$`, (*array)[row][column]); ok {
			parsedDate, err := time.Parse("2006/01/02", (*array)[row][column])
			if err != nil {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			}
			date = parsedDate.Local()
		} else if ok, _ := regexp.MatchString(`^\d{8}$`, (*array)[row][column]); ok {
			parsedDate, err := time.Parse("20060102", (*array)[row][column])
			if err != nil {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
			}
			date = parsedDate.Local()
		} else {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
		}
		if !date.IsZero() {
			if date.Year() < minYear {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "年份[" + strconv.Itoa(date.Year()) + "]小于" + strconv.Itoa(minYear)})
			} else if date.Year() > maxYear {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "年份[" + strconv.Itoa(date.Year()) + "]大于" + strconv.Itoa(maxYear)})
			}
		}
		return date
	}
}

func validateStudentIsNew(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string) (studentId int64, password sql.NullString, err error) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
		return 0, sql.NullString{}, nil
	} else {
		student := new(entity.Student)
		err := student.SelectAllBySchoolRollId((*array)[row][column])
		if err == orm.ErrNoRows {
			err = nil
		}
		return student.Id, student.Password, err
	}
}

func validateCurrentGrade(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string, schoolType byte) (currentGrade string) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
	} else {
		if ok, _ := regexp.MatchString(`^\d{2}$`, (*array)[row][column]); !ok {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
		} else if schoolType != 0 {
			schoolTypeStr := entity.SchoolTypeMapCode[schoolType]
			if schoolTypeStr == "小" {
				if ok, _ := regexp.MatchString(`^1[123456]$`, (*array)[row][column]); !ok {
					*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
				}
			} else if schoolTypeStr == "初" {
				if ok, _ := regexp.MatchString(`^2[123]$`, (*array)[row][column]); !ok {
					*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
				}
			} else if schoolTypeStr == "高" {
				if ok, _ := regexp.MatchString(`^3[123]$`, (*array)[row][column]); !ok {
					*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
				}
			} else if schoolTypeStr == "小初" {
				if ok, _ := regexp.MatchString(`^(1[123456])|(2[123])$`, (*array)[row][column]); !ok {
					*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
				}
			} else if schoolTypeStr == "初高" {
				if ok, _ := regexp.MatchString(`^[23][123]$`, (*array)[row][column]); !ok {
					*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
				}
			} else if schoolTypeStr == "小初高" {
				if ok, _ := regexp.MatchString(`^(1[123456])|([23][123])$`, (*array)[row][column]); !ok {
					*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
				}
			}
		}
	}
	return (*array)[row][column]
}

func validateCurrentClass(array *[][]string, row int, column int, errMsg *[]ImportErrorMsg, columnName string, maxYear int, minYear int, schoolType byte) (currentGrade string) {
	if len((*array)[row][column]) == 0 {
		*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "数据未填"})
	} else {
		if ok, _ := regexp.MatchString(`^\d{7}$`, (*array)[row][column]); !ok {
			*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
		} else {
			year, _ := strconv.Atoi((*array)[row][column][0:4])
			if year > maxYear {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]年份大于" + strconv.Itoa(maxYear)})
			} else if year < minYear {
				*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]年份小于" + strconv.Itoa(maxYear)})
			} else if schoolType != 0 {
				schoolTypeStr := entity.SchoolTypeMapCode[schoolType]
				if schoolTypeStr == "小" {
					if ok, _ := regexp.MatchString(`^\d{4}1\d{2}$`, (*array)[row][column]); !ok {
						*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
					}
				} else if schoolTypeStr == "初" {
					if ok, _ := regexp.MatchString(`^\d{4}2\d{2}$`, (*array)[row][column]); !ok {
						*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
					}
				} else if schoolTypeStr == "高" {
					if ok, _ := regexp.MatchString(`^\d{4}3\d{2}$`, (*array)[row][column]); !ok {
						*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
					}
				} else if schoolTypeStr == "小初" {
					if ok, _ := regexp.MatchString(`^\d{4}[12]\d{2}$`, (*array)[row][column]); !ok {
						*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
					}
				} else if schoolTypeStr == "初高" {
					if ok, _ := regexp.MatchString(`^\d{4}[23]\d{2}$`, (*array)[row][column]); !ok {
						*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
					}
				} else if schoolTypeStr == "小初高" {
					if ok, _ := regexp.MatchString(`^\d{4}[123]\d{2}$`, (*array)[row][column]); !ok {
						*errMsg = append(*errMsg, ImportErrorMsg{At: getPosition(row+1, column), Reason: columnName + "[" + (*array)[row][column] + "]格式错误"})
					}
				}
			}
		}
	}
	return (*array)[row][column]
}

func validateScoreIsNew(array *[][]string, row int, column int, measureData time.Time) (scoreId int64, err error) {
	if len((*array)[row][column]) != 0 {
		score := new(entity.Score)
		err := score.SelectAllBySchoolRollIdMeasurementDate((*array)[row][column], measureData)
		if err == orm.ErrNoRows {
			err = nil
		}
		return score.Id, err
	}
	return 0, nil
}

func validateBodyMassIndex(score *entity.Score) {
	if score.Height.Valid && score.Weight.Valid {
		score.BodyMassIndex.Valid = true
		score.BodyMassIndex.Float64 = score.Weight.Float64 / math.Pow(score.Height.Float64/100, 2)
	}
}

func validateSame(sameMap *map[interface{}]int, key interface{}, row int, errMsg *[]ImportErrorMsg) {
	if len(*errMsg) == 0 {
		if sameRow, ok := (*sameMap)[key]; ok {
			*errMsg = append(*errMsg, ImportErrorMsg{At: strconv.Itoa(row+1) + "行", Reason: "与第" + strconv.Itoa(sameRow) + "行冲突"})
		} else {
			(*sameMap)[key] = row + 1
		}
	}
}

func getRowName(i int) (name string) {
	for {
		yushu := i % 26
		name += string(yushu + 'A')
		i = i / 26
		if i == 0 {
			break
		}
	}
	return
}

func getPosition(row int, column int) string {
	return strconv.Itoa(row) + "行" + getRowName(column) + "列"
}
